package cn.itsource.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.itsource.constants.CacheConstants;
import cn.itsource.constants.ErrorCode;
import cn.itsource.constants.RConst;
import cn.itsource.exception.GlobalException;
import cn.itsource.pojo.domain.Login;
import cn.itsource.mapper.LoginMapper;
import cn.itsource.pojo.domain.Permission;
import cn.itsource.pojo.domain.Role;
import cn.itsource.pojo.dto.LoginDto;
import cn.itsource.pojo.vo.LoginSuccessVo;
import cn.itsource.result.JSONResult;
import cn.itsource.service.ILoginService;
import cn.itsource.template.WeChatTemplate;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 登录表 服务实现类
 * </p>
 *
 * @author luoc
 * @since 2024-09-03
 */
@Service
public class LoginServiceImpl extends ServiceImpl<LoginMapper, Login> implements ILoginService {

    @Autowired
    private WeChatTemplate weChatTemplate;
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public JSONResult login(LoginDto loginDto) {
        String openId = weChatTemplate.getOpenId(loginDto.getCode());
        Login one = this.getOne(new LambdaQueryWrapper<Login>()
                .eq(Login::getOpenId, openId)
                .eq(Login::getType, loginDto.getType())
        );
        if (one != null) {
            // 登录成功
            StpUtil.login(one.getId());
            // 保存用户信息
            // StpUtil.getSession().set("currenUser", one);
            LoginSuccessVo loginSuccessVo = LoginSuccessVo.builder()
                    .token(StpUtil.getTokenValue())
                    .avatar(one.getAvatar())
                    .nickName(one.getNickName())
                    .phone(one.getPhone())
                    .build();
            // 加载权限 & 角色信息到redis
            this.getPermissionList(one.getId());
            this.getRoleList(one.getId());
            return JSONResult.success(loginSuccessVo);
        }else {
            throw new GlobalException(ErrorCode.NOT_USER);
        }
    }

    @Override
    public List<String> getPermissionList(Long loginId) {
        String key = CacheConstants.CURRENT_USER_PERMISSIONS + loginId;
        if (redisTemplate.hasKey(key)){
            return (List<String>) redisTemplate.opsForValue().get(key);
        }
        List<Permission> permissions = loginMapper.getPermissionByLoginId(loginId);
        List<String> res = permissions.stream().map(Permission::getSn).collect(Collectors.toList());
        redisTemplate.opsForValue().set(key, res, RConst.Num.INT_12, TimeUnit.HOURS);
        return res;
    }

    @Override
    public List<String> getRoleList(Long loginId) {
        String key = CacheConstants.CURRENT_USER_ROLES + loginId;
        if (redisTemplate.hasKey(key)){
            return (List<String>) redisTemplate.opsForValue().get(key);
        }
        List<Role> roles = loginMapper.getRoleByLoginId(loginId);
        List<String> res = roles.stream().map(Role::getSn).collect(Collectors.toList());
        redisTemplate.opsForValue().set(key, res, RConst.Num.INT_12, TimeUnit.HOURS);
        return res;
    }
}
